package com.efrei.uchat.model.croom;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;

import com.efrei.uchat.io.Session;
import com.efrei.uchat.utils.Const;

public class Crooms {
	
	private static Logger logger = Logger.getLogger(Crooms.class);
	
	private Map<String, Croom> crooms = new HashMap<String, Croom>();
	
	public Crooms() {
		// default croom: public
		crooms.put(Const.PUBLIC_CROOM, new Croom(Const.PUBLIC_CROOM));
	}
	
	/**
	 * @see Crooms#joinCroom(Session, String, String)
	 */
	public CroomMessageStatus joinCroom(Session session, String topic) {
		return joinCroom(session, topic, null);
	}
	
	/**
	 * assign session with croom defined by his topic & optionnal password
	 * @param session
	 * @param topic
	 * @param password null if not used
	 * @return SUCCESS OR FORBIDDEN
	 */
	public CroomMessageStatus joinCroom(Session session, String topic, String password) {
		Croom croom;
		
		if(!crooms.containsKey(topic)) {
			// unknown croom, create with this chatter
			logger.info("created unknown croom "+topic);
			croom = (password == null?
					new Croom(topic):
					new Croom(topic, password));
			crooms.put(topic, croom);
			croom.addSession(session);
		} else {
			croom = crooms.get(topic);
			if(croom.isPrivate()) {
				if(password == null ||
						!croom.getPassword().equals(password)) {
					System.out.println("invalid password, expected "+croom.getPassword());
					// password missing or invalid
					return CroomMessageStatus.FORBIDDEN;
				}
			}
			System.out.println(session.getChatter().getPseudo()+" join "+croom.getTopic());
			croom.addSession(session);
		}
		return CroomMessageStatus.SUCCESS;
	}

	public Set<Croom> disconnect(Session session) {
		Set<Croom> ret = new HashSet<Croom>();
		
		StringBuilder bb = new StringBuilder();
		bb.append("Crooms: remove ")
			.append(session.getChatter())
			.append(" for croom(s) ");
		for (Croom croom : crooms.values()) {
			if(croom.contains(session)) {
				croom.removeSession(session);
				ret.add(croom);
				bb.append(", ").append(croom);
			}
		}
		logger.info(bb.append(" !").toString());
		
		return ret;
	}
	
	/**
	 * @param topic
	 * @return croom or null if not known
	 */
	public Croom getCroom(String topic) {
		return crooms.get(topic);
	}
	
	public Map<String, Croom> getCrooms() {
		return crooms;
	}

	public Croom remove(String croom) {
		return crooms.remove(croom);
	}
}
